#ifndef CMD_USER_SESSION_H
#define CMD_USER_SESSION_H 

#include "cmd_node.h"
#include "cmd_view.h"

#include <boost/shared_ptr.hpp>
#include <boost/signal.hpp>

#include <sstream>
#include <iostream>
#include <vector>

namespace vpm 
{
	namespace cmo 
	{

		class CmdUserSession
		{
		public:
			typedef boost::signal<void (const char * )> WriteStringSignal;
			typedef boost::signal<void (char)>    WriteCharSignal;

			CmdUserSession(CmdViewPtr & );

			bool is_login()
			{
				//if the user name is empty , we assume it needn't login
				if (m_cmdView->m_viewUser.empty())
				{
					return true; 
				}
				return m_bLogin;
			}

			bool login(const std::string & user, const std::string & pass)
			{
				if (user == m_cmdView->m_viewUser && (m_cmdView->m_viewPass.empty() || m_cmdView->m_viewPass == pass))
				{				
					m_bLogin = true; 
					return true; 									
				}
				return false; 
			}

			void logout()
			{
				m_bLogin = false; 
			}

			void rewind();

			void tab_action(); 

			void nonspace_action(char ch);
			
			bool space_action();

			void control_action(char ch);

			void enter_action();

			CmdViewPtr cmd_view()
			{
				return m_cmdView; 
			}

			void outln()
			{
#ifdef WIN32
				m_stringWriter("\r\n");
#else 
				m_stringWriter("\n");
#endif 
				m_stringWriter(m_cmdView->m_viewPrompt.c_str()) ;
			}
		
		private:
			friend class CmdUserSessionAccess; 
			
			std::vector<char> m_inputWord;
			std::stringstream m_validInput;
			CmdNodePtr m_seekNode; 

			bool m_bStart;
			bool m_bLogin; 
			bool m_bCmdFinished;

			CmdViewPtr  m_cmdView;

			WriteStringSignal m_stringWriter;
			WriteCharSignal   m_charWriter;		
		};

		typedef boost::shared_ptr<CmdUserSession> CmdUserSessionPtr;

		class CmdUserSessionAccess
		{
		public:
			static void attach_string_writer(CmdUserSession & session,CmdUserSession::WriteStringSignal::slot_function_type writer)
			{
				session.m_stringWriter.connect( writer);
			}

			static void attach_char_writer(CmdUserSession & session,CmdUserSession::WriteCharSignal::slot_function_type writer)
			{
				session.m_charWriter.connect( writer);
			}
		};
	}
}

#endif // 










